package com.example.rizhaoscienceandtechnologymuseum.View;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;

import com.am.fras.License;
import com.am.fras.LicenseError;
import com.authen.facecompare.activity.ModelInit;
import com.authen.facecompare.extractfeaturn.ExtractFeature;
import com.common.pos.api.util.PosUtil;
import com.example.baselibrary.Base.BaseActivity;
import com.example.baselibrary.Base.BaseCustomer;

import com.example.baselibrary.Utils.LogUtil;
import com.example.baselibrary.Utils.SelfToastUtil;
import com.example.baselibrary.Utils.StringUtil;
import com.example.baselibrary.Utils.TimeCountDownUtil;
import com.example.rizhaoscienceandtechnologymuseum.Bean.CheckTicketRequsetBean;
import com.example.rizhaoscienceandtechnologymuseum.Bean.CheckTicketResultBean;

import com.example.rizhaoscienceandtechnologymuseum.Bean.JJHLoginBean;
import com.example.rizhaoscienceandtechnologymuseum.Bean.JJHLoginResult;
import com.example.rizhaoscienceandtechnologymuseum.RetrufitHelp.BaseSubscriber;
import com.example.rizhaoscienceandtechnologymuseum.RetrufitHelp.ExceptionHandle;
import com.example.rizhaoscienceandtechnologymuseum.RetrufitHelp.RetrofitClient;
import com.example.baselibrary.Utils.SPUtils;
import com.example.rizhaoscienceandtechnologymuseum.R;
import com.example.rizhaoscienceandtechnologymuseum.Server.AppRestartService;
import com.example.rizhaoscienceandtechnologymuseum.Server.IDSearchService;
import com.example.rizhaoscienceandtechnologymuseum.Server.RefreshTokenService;
import com.example.rizhaoscienceandtechnologymuseum.Server.VoiceService;
import com.example.rizhaoscienceandtechnologymuseum.Utils.BottomKouLingDialog;
import com.example.rizhaoscienceandtechnologymuseum.Utils.BottomSettingDialog;
import com.example.rizhaoscienceandtechnologymuseum.Utils.CameraView;
import com.example.rizhaoscienceandtechnologymuseum.Utils.FaceStock;
import com.example.rizhaoscienceandtechnologymuseum.Utils.FaceView;
import com.example.rizhaoscienceandtechnologymuseum.Utils.MachineID;
import com.example.rizhaoscienceandtechnologymuseum.Utils.TimeUtil;
import com.telpo.tps550.api.idcard.IdentityMsg;

import java.io.File;
import java.util.Timer;
import java.util.TimerTask;

public class MainActivity extends BaseActivity {

    //登入服务器
    private JJHLoginBean jjhLoginBean;
    private String machineid;

    private ImageView ivFaceId;
    private ImageView ivFaceNow;
    private ImageView ivResultIcon;
    private CameraView colorCamera;
    private FaceView faceView;
    private ImageView ivShow;
    private ImageView idShow;
    private String gateNo;
    private CheckTicketRequsetBean ticketRequsetBean;
    private FaceStock faceStock;

    private long timeNew;
    private long timeOld;
    private String OldID;
    private String OldFace;

    //灯光控制
    private int ledIsAutoOpen;
    private int monitor_cycle;
    private int lightValue;

    private SharedPreferences sp = null;

    private Bitmap IdFace;
    private Bitmap bitmatCut;
    private Intent searchService;
    private Intent voiceService;

    private int LowestValue = 60;


    //如果不在检票，如果检测到有人，那么就播报欢迎光临，等一些文字
    private boolean isCheck = false;


    //如果处于检票界面，那么当身份证放入的时候就不响应

    //结果页面，两个人脸显示的标记
    private boolean isIDFace = false;
    private boolean isNowFace = false;

    //    private LinearLayout llPreparFace;
    private RelativeLayout rlFacePick;
    private RelativeLayout rlCheckResult;
    private Timer timer;

    private static setShowLvKuang showLvKuang;
    Handler mHandler = new Handler() {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            if (msg.what == 0) {
                if (isCheck == false) {
                    //如果不在检票，如果检测到有人，那么就播报欢迎光临，等一些文字
//                    IdFace = null;
//                    bitmatCut = null;
                    if (IdFace == null && bitmatCut != null) {
                        VoiceService.PlayAudioFile("请将身份证放于下方感应区");
                    }
                    if (IdFace != null && bitmatCut == null) {
                        VoiceService.PlayAudioFile("请将人脸正对屏幕");
                    }
                    if (IdFace == null && bitmatCut == null) {
                        VoiceService.PlayAudioFile("欢迎光临日照科技馆");
                    }

                } else {
                    ivShow.setImageResource(R.drawable.faceholder);
                    idShow.setImageResource(R.drawable.faceholder);
                }
            }
        }
    };
    private String idString;
    private TextView tvResult;
    private TextView tvPassNumber;
    private TextView tvPointName;
    private TextView tvTimeShow;
    private Button btBack;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    protected int getView() {
        return R.layout.activity_main;
    }

    @Override
    public void init() {

        // 一 进来就要 进行登录获取 token值
        MachineID.getInstance().setGetMachineidListener(MainActivity.this, new MachineID.getMachineIdLietener() {
            @Override
            public void getID(String id) {
                machineid = id;
                // 一进来就要登录
                LoginApp();
            }
        });

        if (ticketRequsetBean == null) {
            ticketRequsetBean = new CheckTicketRequsetBean();
        }

//        llPreparFace = findViewById(R.id.ll_prepar_face);
        rlFacePick = findViewById(R.id.rl_face_pick);
        rlFacePick = findViewById(R.id.rl_face_pick);
        rlCheckResult = findViewById(R.id.rl_check_for_result);

        ivFaceId = findViewById(R.id.iv_id_face);
        ivFaceNow = findViewById(R.id.iv_now_face);
        ivResultIcon = findViewById(R.id.iv_result_icon);
        colorCamera = findViewById(R.id.surface_0);
        faceView = findViewById(R.id.faceView);
        ivShow = findViewById(R.id.iv_test);
        idShow = findViewById(R.id.iv_test_id);
        tvTimeShow = findViewById(R.id.tv_time_show);
        btBack = findViewById(R.id.bt_back);


        //检票结果显示
        tvResult = findViewById(R.id.tv_check_result);
        tvPassNumber = findViewById(R.id.tv_pass_number);
        tvPointName = findViewById(R.id.tv_pass_point_name);

        showFacePick();

        sp = this.getSharedPreferences("gate", Context.MODE_PRIVATE);
        //灯光自动控制功能
        ledIsAutoOpen = sp.getInt("ledIsAutoOpen", 2);
        monitor_cycle = sp.getInt("monitor_cycle", 10);
        lightValue = sp.getInt("lightValue", 30);
        //摄像头预览功能
        faceStock = new FaceStock();

        colorCamera.setFaceStock(faceStock, ledIsAutoOpen == 1, monitor_cycle, lightValue);
        colorCamera.setFaceView(faceView);
        colorCamera.setfaecCutListener(new CameraView.setfaecCut() {
            @Override
            public void faecCut(Bitmap bitmatC) {
                bitmatCut = bitmatC;
                timeNew = TimeUtil.getLocationTimeLong();
                if (checkFaceAgain("")) {
                    return;
                }

                //这个地方就是采集人脸显示出来的地方
                if (bitmatCut != null) {
                    if (IdFace != null) {
                        //  如果两个人脸都不为空，那么就去做人证对比
                        ComparBitmap(IdFace, bitmatCut);

                    }
                    ivShow.setImageBitmap(bitmatCut);
                }

            }
        });

        //485接收模式
//        PosUtil.setRs485Status(0);//接收模式
        //启动身份证的检查身份证的模块
        searchService = new Intent(MainActivity.this, IDSearchService.class);
        startService(searchService);
        // 启动声音服务模块
        voiceService = new Intent(MainActivity.this, VoiceService.class);
        startService(voiceService);

        BottomKouLingDialog.setShowSettingListener(new BottomKouLingDialog.setShowSetting() {
            @Override
            public void showSetting() {
                BottomSettingDialog bottomSettingDialog = new BottomSettingDialog(MainActivity.this);
                bottomSettingDialog.show();
            }
        });

        initFace();
        doThing();
        timerPrepar();

        TimeCountDownUtil.setTimeOverListener(new TimeCountDownUtil.TimeOver() {
            @Override
            public void timeOverNow() {
                // 倒计时完成后的操作
                showFacePick();
                tvTimeShow.setVisibility(View.GONE);
            }

            @Override
            public void timeShow(String timeShow) {
                tvTimeShow.setVisibility(View.VISIBLE);
                tvTimeShow.setText("结果倒计时:" + timeShow);
            }
        });

        //守护service
        Intent intent = new Intent(this, AppRestartService.class);
        startService(intent);

        BottomSettingDialog.SettingConfigListener(new BottomSettingDialog.SettingConfig() {
            @Override
            public void settingCon() {
                LoginApp();
            }
        });
    }

    private void LoginApp() {
        if (machineid == null) {
            SelfToastUtil.getInstance().show("请重新开机");
            return;
        }
        jjhLoginBean = new JJHLoginBean("kjg", "888888", "1", machineid);
        final String base = (String) SPUtils.get(MainActivity.this, BaseCustomer.BASE_URL, "");
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                showDialogTip("链接服务器中。。。");
                RetrofitClient.getInstance(MainActivity.this, base).JJHLogin(jjhLoginBean, new BaseSubscriber<JJHLoginResult>(MainActivity.this) {
                    @Override
                    public void onError(ExceptionHandle.ResponeThrowable e) {
                        dissDiglogTip();
                        LogUtil.d("登录失败");
                        SelfToastUtil.getInstance().show(e.message);
                    }

                    @Override
                    public void onNext(JJHLoginResult jjhLoginResult) {
                        dissDiglogTip();
                        if (jjhLoginResult.getCode().equals("200")) {
                            // 保存 token 后期接口 调用
                            SPUtils.put(MainActivity.this, BaseCustomer.ACCESSTOKEN, jjhLoginResult.getData().getUserInfo().getAccessToken());
                            SPUtils.put(MainActivity.this, BaseCustomer.REFSHTOKEN, jjhLoginResult.getData().getUserInfo().getRefreshToken());
                            startService(new Intent(MainActivity.this, RefreshTokenService.class));
                            // 登录成功，那么就启动自动更新服务

                            LogUtil.d("登录成功");
                        } else {
                            //对失败进行反馈
                            LogUtil.d("登录失败");
                            SelfToastUtil.getInstance().show(jjhLoginResult.getMessage());
                        }
                    }
                });
            }
        });

    }

    private void timerPrepar() {
        timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                // (1) 使用handler发送消息
                Message message = new Message();
                message.what = 0;
                mHandler.sendMessage(message);
            }
        }, 0, 1000 * 20);//每隔一秒使用handler发送一下消息,也就是每隔10秒执行一次,一直重复执行
    }

    private void ComparBitmap(Bitmap idFace, Bitmap bitmatCut) {
        byte[] idCome = ExtractFeature.getFeatureOrCompareByBitmap(idFace, idFace.getWidth(), idFace.getHeight(), 0);
        byte[] cutCome = ExtractFeature.getFeatureOrCompareByBitmap(bitmatCut, bitmatCut.getWidth(), bitmatCut.getHeight(), 0);
        if (idCome != null && cutCome != null) {
            int score = (int) ExtractFeature.getCompareScore(idCome, cutCome);
            if (score > LowestValue) {
                // 如果人脸对比分数过了，就去显示检票结果页面
                showFaceResult(idFace, bitmatCut);

            } else {
                SelfToastUtil.getInstance().show("人证核验失败，请重新确认人脸");
//                faceCheck++;
//                //如果大于5次，那么就重头来
//                VoiceService.PlayAudioFile("请将人脸正对屏幕");
//                if (faceCheck > 3) {
//                    showFacePrePar();
//                    VoiceService.PlayAudioFile("抱歉，人证核验未通过");
//                }
            }
//            SelfToastUtil.getInstance().show("人证对比分数" + score);
        }

    }


    private void initFace() {
        //（人脸识别初始化模型）
        ModelInit.getModelDirMap(MainActivity.this);
        ModelInit.initFras();  //初始化授权库
        ModelInit.initAnti();  //fw授权库

        //调用系统摄像头API
        //防伪认证
        if (!verifyLicensefw())
            return;

        //授权认证
        if (!verifyLicense())
            return;

    }


    private void doThing() {

        btBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showFacePick();
                tvTimeShow.setVisibility(View.GONE);
                TimeCountDownUtil.closeCountTime();
            }
        });

        findViewById(R.id.tv_test_sh).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                BottomKouLingDialog bottomKouLingDialog = new BottomKouLingDialog(MainActivity.this);
                bottomKouLingDialog.show();
            }
        });

        // 身份证 回调   身份证回调
        IDSearchService.setIDInfoListener(new IDSearchService.IdInfo() {
            @Override
            public void IdInfo(Bitmap bitmap, IdentityMsg info) {

                // 有身份证 刷的时候，要去判断三个地方是否有设置
                if (StringUtil.isNullOrEmpty((String) SPUtils.get(MainActivity.this, BaseCustomer.BASE_URL, ""))) {
                    SelfToastUtil.getInstance().show("基础地址为空，请联系管理员配置");
                    return;
                }
                if (StringUtil.isNullOrEmpty((String) SPUtils.get(MainActivity.this, BaseCustomer.CHECK_GATENO, ""))) {
                    SelfToastUtil.getInstance().show("终端未绑定，请联系管理员配置");
                    return;
                }
                if (StringUtil.isNullOrEmpty((String) SPUtils.get(MainActivity.this, BaseCustomer.FACEVALUE, ""))) {
                    SelfToastUtil.getInstance().show("人脸阈值为空，请联系管理员配置");
                    return;
                }

                timeNew = TimeUtil.getLocationTimeLong();
                idString = info.getNo();
                if (!checkIDAgain(idString)) {
                    TimeCountDownUtil.closeCountTime();
                    LogUtil.d("去干活了----" + TimeUtil.getLocationTime());
                    ivFaceId.setImageBitmap(bitmap);
                    idShow.setImageBitmap(bitmap);
                    //  如果人脸不为空，那么就保存人脸，然后切换页面
                    if (bitmap != null) {
                        IdFace = bitmap;
                    }
                }
            }
        });

        ivResultIcon.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int ret = -1;
                ret = PosUtil.setRelayPower(1);
                Toast.makeText(MainActivity.this, "" + ret, Toast.LENGTH_SHORT).show();
            }
        });

    }

    // 条件满足后，就要去检票（人证对比，通过后，用身份证去检票啦）
    private void CheckIDForResult() {
        showDialogTip("检票中。。。");
        gateNo = (String) SPUtils.get(MainActivity.this, BaseCustomer.CHECK_GATENO, "");

        ticketRequsetBean.setCheckCount(-1);
        ticketRequsetBean.setSearchDataType("2");  // 1 是二维码，2是身份证
        ticketRequsetBean.setSearchData(idString);
        ticketRequsetBean.setAddress("");
        ticketRequsetBean.setGateNo(gateNo);
        ticketRequsetBean.setIsCollectionGate("N");
        ticketRequsetBean.setSign("");
        ticketRequsetBean.setTimestamp(TimeUtil.getLocationTimeNew(TimeUtil.FORMAT_DAY_EN_ZYF));
        RetrofitClient.getInstance(MainActivity.this, baseUrl, headers).CheckTicket(ticketRequsetBean, new BaseSubscriber<CheckTicketResultBean>(MainActivity.this) {
            @Override
            public void onError(ExceptionHandle.ResponeThrowable e) {
                dissDiglogTip();
                SelfToastUtil.getInstance().show(e.message);
                TimeCountDownUtil.CountDownTime(10);
            }

            @Override
            public void onNext(CheckTicketResultBean jjhLoginResult) {
                dissDiglogTip();
                TimeCountDownUtil.CountDownTime(10);
                if (jjhLoginResult.getCode().equals("200")) {
                    ShowSuccessFace(jjhLoginResult);
                    VoiceService.PlayAudioFile(jjhLoginResult.getMessage());
                    PosUtil.setRelayPower(0);//关闭继电器
                    PosUtil.setRelayPower(1);//打开继电器
                } else {
                    if (jjhLoginResult.getMessage() != null) {
                        VoiceService.PlayAudioFile(jjhLoginResult.getMessage());
                        ShowErrorFace(jjhLoginResult.getMessage());
                    } else {
                        ShowErrorFace("");
                    }

                }
            }
        });
    }

    private void ShowSuccessFace(CheckTicketResultBean jjhLoginResult) {
        tvResult.setText("验证成功");
        tvResult.setTextColor(getResources().getColor(R.color.color_duck_green));
        tvPassNumber.setText("通行人数：" + jjhLoginResult.getData().getPassPersonSum());
        tvPassNumber.setTextColor(getResources().getColor(R.color.color_duck_green));

        ivResultIcon.setBackgroundResource(R.drawable.passface);

        // 验票成功后，要清除数据
        IdFace = null;
        bitmatCut = null;
        idShow.setImageResource(R.drawable.faceholder);
        ivShow.setImageResource(R.drawable.faceholder);
    }

    private void ShowErrorFace(String message) {
        tvResult.setText("验证失败");
        tvResult.setTextColor(getResources().getColor(R.color.rz_error_color));
        tvPassNumber.setText("失败原因：" + message);
        tvPassNumber.setTextColor(getResources().getColor(R.color.rz_error_color));

        ivResultIcon.setBackgroundResource(R.drawable.errorface);

        // 验票成功后，要清除数据
        IdFace = null;
        bitmatCut = null;
        idShow.setImageResource(R.drawable.faceholder);
        ivShow.setImageResource(R.drawable.faceholder);
    }

    private void ShowFace() {
        tvResult.setText("验票中");
        tvResult.setTextColor(getResources().getColor(R.color.color_gray));
        tvPassNumber.setText("请稍等");
        tvPassNumber.setTextColor(getResources().getColor(R.color.color_gray));

        ivResultIcon.setBackgroundResource(R.drawable.shape_white);
    }


//    private void showFacePrePar() {
////        llPreparFace.setVisibility(View.VISIBLE);
//        rlFacePick.setVisibility(View.GONE);
//        rlCheckResult.setVisibility(View.GONE);
//
//        IdFace = null;
//
//        isIDFace = false;
//        isNowFace = false;
//
//    }

    private void showFacePick() {
//        isCheckFace = false;
        isCheck = false;
        ShowFace();
//        llPreparFace.setVisibility(View.GONE);
        rlFacePick.setVisibility(View.VISIBLE);
        rlCheckResult.setVisibility(View.GONE);

        isIDFace = false;
        isNowFace = false;

        //在人脸捕捉的时候，去显示框框
        if (showLvKuang != null) {
            showLvKuang.showLvKuang(true);
        }

    }

    private void showFaceResult(Bitmap idFace, Bitmap bitmatCut) {
        isCheck = true;
        rlFacePick.setVisibility(View.GONE);
        rlCheckResult.setVisibility(View.VISIBLE);

        //在人脸捕捉的时候，去显示框框
        if (showLvKuang != null) {
            showLvKuang.showLvKuang(false);
        }
        //如果
        if (!isIDFace && !isNowFace) {
            ivFaceId.setImageBitmap(idFace);
            isIDFace = true;

            ivFaceNow.setImageBitmap(bitmatCut);
            isNowFace = true;

            //这个时候就去检票
            CheckIDForResult();
        }
    }


    //识别授权认证
    private boolean verifyLicense() {
        boolean ret = false;
        String licPath = getLicPath("tplicense");
        Log.e("ljj", "licpath=" + licPath);
        int flag = License.verifyLicense(licPath);
        if (flag != LicenseError.AM_E_SUCCESS) {
            //sendLiveImage("识别授权不通过 请检查/sdcard/tplicense/是否有授权文件");

        } else {
            ret = true;
        }
        return ret;
    }

    //活体授权认证
    private boolean verifyLicensefw() {
        boolean ret = false;
        String licPath = getLicPath("fwlicense");
        Log.e("ljj", "fwlicpath=" + licPath);
        if (com.am.antispoof.License.verifyLicense(licPath) == LicenseError.AM_E_SUCCESS) {
            //sendLiveImage("活体授权不通过 请检查/sdcard/fwlicense/是否有授权文件");
            ret = true;

        } else {
        }
        return ret;
    }

    //识别授权目录
    private String getLicPath(String folder) {
        final File parentPath = Environment.getExternalStorageDirectory();
        String storagePath = "";
        if (storagePath.equals("")) {
            storagePath = parentPath.getAbsolutePath() + "/" + folder;
            File f = new File(storagePath);
            if (!f.exists()) {

                f.mkdir();
            }
        }
        storagePath = new StringBuilder(storagePath).append("/").append("license").append(".dat").toString();
        return storagePath;
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        stopService(searchService);
        stopService(voiceService);
    }

    // 返回 true  相同 小于  30 秒  那么就 不处理
    private boolean checkIDAgain(String m_strIDCards) {
        if (m_strIDCards.equals(OldID) && timeNew - timeOld < 1000 * 10) {
            System.out.println("zyf  未超过10秒 拒绝访问" + TimeUtil.getLocationTime());
            return true;
        } else {
            System.out.println("zyf  超过10秒 去访问" + TimeUtil.getLocationTime());
            timeOld = timeNew;
            OldID = m_strIDCards;
            return false;
        }
    }

    private boolean checkFaceAgain(String m_strIDCards) {
        if (m_strIDCards.equals(OldID) && timeNew - timeOld < 1000 * 1) {
            System.out.println("zyf  未超过1秒 拒绝访问" + TimeUtil.getLocationTime());
            return true;
        } else {
            System.out.println("zyf  超过1秒 去访问" + TimeUtil.getLocationTime());
            timeOld = timeNew;
            OldFace = m_strIDCards;
            return false;
        }
    }

    public interface setShowLvKuang {
        void showLvKuang(boolean isShow);
    }

    public static void setShowLvKuangListener(setShowLvKuang show) {
        showLvKuang = show;
    }
}
